import java.io.InputStreamReader;
import java.util.*;

public class Main {

    // 全局锁
    static boolean globalLockIsOk = false;
    // 全局寄存变量
    static HashMap<String, Integer> globalFields = new HashMap<>();
    // 全局就绪队列
    static Deque<ProgramObject> prepareQueue = new LinkedList<>();
    // 全局阻塞队列
    static Queue<ProgramObject> blockQueue = new LinkedList<>();
    // 当前拥有的可支配线程数
    static int hasThreads;
    // 每个程序拥有的时间片
    static int programTime;
    // 每个语句消耗时间片
    private static int amountTime;
    private static int addTime;
    private static int printTime;
    private static int lockTime;
    private static int unlockTime;
    private static int yieldTime;
    private static int endTime;
    // 每个程序的名字
    static int programName = 1;

    // 程序入口
    public static void main(String[] args) {
        InputStreamReader br = new InputStreamReader(System.in);
        Scanner in = new Scanner(br);
        int starterLine = 0;
        while (in.hasNextLine()) {
            String inputStr = in.nextLine();
            if (starterLine == 0) {
                // 第一行:配置参数
                monitorSetting(inputStr);
                System.out.println("第一行参数");
            } else if (!inputStr.isEmpty()) {
                // n+1行:读取程序语句
                monitorSentence(inputStr);
                System.out.println("这行语句" + inputStr);
            } else {
                // 输入解析完毕:执行准备队列
                System.out.println("读取完毕,程序分别是 start: =================");
                prepareQueue.forEach(System.out::println);
                System.out.println("读取完毕,程序分别是 end: =================");

                while (!prepareQueue.isEmpty()) {
                    //  如果有线程空余,那么去准备队列拿程序去执行
                    if (hasThreads != 0) {
                        System.out.println("当前线程数量:" + hasThreads);
                        System.out.println("当前就绪队列中程序数量:" + prepareQueue.size());
                        ProgramObject programObject = prepareQueue.poll();
                        if (!Objects.isNull(programObject)) {
                            System.out.println("执行程序:" + programObject);
                            programObject.execute();
                            // 消耗一个线程
                            hasThreads--;
                        }
                    }
                }
                System.out.println("就绪队列为空程序不在执行");
            }
            starterLine++;
        }
    }

    // 分析输入第一行
    public static void monitorSetting(String inputStr) {
        String[] settingArray = inputStr.split(" ");
        // 1:线程数
        hasThreads = Integer.parseInt(settingArray[0]);
        // 2:每个程序总时间
        programTime = Integer.parseInt(settingArray[1]);
        // 3:=
        amountTime = Integer.parseInt(settingArray[2]);
        // 4:+=
        addTime = Integer.parseInt(settingArray[3]);
        // 5:print
        printTime = Integer.parseInt(settingArray[4]);
        // 6:lock
        lockTime = Integer.parseInt(settingArray[5]);
        // 7:unlock
        unlockTime = Integer.parseInt(settingArray[6]);
        // 8:yield
        yieldTime = Integer.parseInt(settingArray[7]);
        // 9:end
        endTime = Integer.parseInt(settingArray[8]);
    }

    // 每个program拥有的语句
    static ArrayList<String> sentences = new ArrayList<>();

    // 分析第2 ~ n行
    static void monitorSentence(String sentenceStr) {
        sentences.add(sentenceStr);
        if ("end".equals(sentenceStr)) {
            prepareQueue.offer(new ProgramObject(programName, sentences));
            sentences = new ArrayList<>();
            programName++;
        }
    }


    static class ProgramObject {
        // 程序名
        int programName;
        // 限制时间
        int limitTime = programTime;
        // 当前程序执行位置
        int curIndex = 0;
        // 解析后的程序
        ArrayList<String> sentences;

        public ProgramObject(int programName, ArrayList<String> sentences) {
            System.out.println("程序" + programName + "初始化");
            this.programName = programName;
            this.sentences = sentences;
        }

        // 超出限制时间?
        private boolean isTimeUp(int i, int time) {

            limitTime = limitTime - time;
            if (limitTime < 1) {
                limitTime = programTime;
                // 记录下次执行位置
                curIndex = i + 1;
                // 时间耗尽进入就绪队列尾部
                prepareQueue.offer(this);
                System.out.println("程序:" + programName + "- 时间片耗尽");
                System.out.println("下次执行语句index:" + curIndex);
                // 归还线程
                hasThreads++;
                return true;
            }

            return false;
        }

        public void execute() {
            System.out.println("开始执行程序:" + programName);
            // 从上次未执行完的地方执行
            for (int i = curIndex; i < sentences.size(); i++) {
                String programLine = sentences.get(i);
                // 加法
                if (programLine.contains("+=")) {
                    System.out.println("执行+=");
                    String[] lineAry = programLine.replace("+=", ".").split("\\.");
                    String field = lineAry[0].trim();
                    Integer fieldValue = Integer.parseInt(lineAry[1].trim());
                    if (globalFields.get(field) == null) {
                        globalFields.put(field, fieldValue);
                    } else {
                        Integer globalFieldValue = globalFields.get(field);
                        globalFields.put(field, globalFieldValue + fieldValue);
                    }
                    if (isTimeUp(i, addTime)) {
                        break;
                    }
                }
                // 赋值
                if (programLine.contains("=")) {
                    System.out.println("执行=");
                    String[] lineAry = programLine.split("=");
                    String field = lineAry[0].trim();
                    String fieldValue = lineAry[1].trim();
                    // 等号右边是数字还是字符?
                    boolean fieldValueIsNum = fieldValue.chars().allMatch(Character::isDigit);
                    int fieldValueNum;
                    if (fieldValueIsNum) {
                        // 是数字直接变量赋值
                        fieldValueNum = Integer.parseInt(fieldValue);
                    } else {
                        // 是字符传递引用
                        fieldValueNum = globalFields.getOrDefault(fieldValue, 0);
                    }
                    globalFields.put(field, fieldValueNum);
                    if (isTimeUp(i, amountTime)) {
                        break;
                    }
                }
                // 加锁
                if (programLine.contains("lock") && !programLine.contains("unlock")) {
                    System.out.println("执行lock");
                    //试图加锁
                    if (globalLockIsOk) {
                        System.out.println("加锁失败,此程序进入阻塞队列");
                        limitTime = programTime;
                        // 记录下次执行位置
                        curIndex = i + 1;
                        // 加锁失败进入阻塞队列
                        blockQueue.offer(this);
                        System.out.println("当前阻塞队列:" + blockQueue);
                        break;
                    }
                    globalLockIsOk = true;
                    if (isTimeUp(i, lockTime)) {
                        break;
                    }

                }
                // 解锁
                if (programLine.contains("unlock")) {
                    System.out.println("执行unlock");
                    globalLockIsOk = false;
                    ProgramObject programObject = blockQueue.poll();
                    prepareQueue.offerFirst(programObject);
                    if (isTimeUp(i, unlockTime)) {
                        break;
                    }
                }
                // 挂起
                if (programLine.contains("yield")) {
                    System.out.println("执行yield");
                    curIndex = i + 1;
                    // 进入就绪队列尾部
                    prepareQueue.offer(this);
                    hasThreads++;
                    break;
                }
                // 打印
                if (programLine.contains("print")) {
                    System.out.println("执行print");
                    String[] lineAry = programLine.split(" ");
                    String field = lineAry[1].trim();
                    Integer fieldValue = globalFields.get(field);
                    System.out.println(programName + ":" + fieldValue);
                    if (isTimeUp(i, printTime)) {
                        break;
                    }
                }
                // 结束
                if (programLine.contains("end")) {
                    System.out.println("执行end");
                    System.out.println("=======>程序:" + programName + "运行结束<==============");
                    hasThreads++;
                    break;
                }
            }
        }

        @Override
        public String toString() {
            return "ProgramObject{" +
                    "programName=" + programName +
                    ", limitTime=" + limitTime +
                    ", curIndex=" + curIndex +
                    ", sentences=" + sentences +
                    '}';
        }
    }
}
